package baiqitun.stupro.common.workflow.task;

import baiqitun.stupro.common.enums.BooleanEnum;
import baiqitun.stupro.common.workflow.enums.ProcessVariableEnum;
import baiqitun.stupro.common.workflow.exception.WorkflowException;
import baiqitun.stupro.common.workflow.exception.enums.WorkflowExceptionEnum;
import baiqitun.stupro.common.workflow.util.HistoryUtil;
import baiqitun.stupro.common.workflow.util.RepositoryUtil;
import baiqitun.stupro.common.workflow.util.TaskUtil;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * 此类应用于在流程图中前一个节点为UserTask节点的ServiceTask类型的流程节点
 * 当被处理的任务的结果在逻辑上只有true和false两种情况时，ServiceTask节点应该使用此类进行处理
 * @author kedaji
 */

public abstract class AbstractBooleanServiceTaskHandler implements ServiceTaskHandler {
    @Autowired
    protected TaskUtil taskUtil;
    @Autowired
    protected HistoryUtil historyUtil;
    @Autowired
    protected RepositoryUtil repositoryUtil;

    protected ProcessVariableEnum processVariableEnum;

    @Override
    public void execute(DelegateExecution execution) {
        if (processVariableEnum == null){
            processVariableEnum = ProcessVariableEnum.RESULT;
        }
        String resultValue = (String) execution.getVariable(processVariableEnum.name());

        if (BooleanEnum.TRUE.getValue().equals(resultValue)){
            handleTrue(execution);
        } else if (BooleanEnum.FALSE.getValue().equals(resultValue)){
            handleFalse(execution);
        } else {
            throw new WorkflowException(WorkflowExceptionEnum.UNKNOWN_PROCESS_VARIABLE).put(processVariableEnum.name(), resultValue);
        }
    }

    /**
     * 当前置的UserTask的处理结果逻辑上为True时ServiceTask节点的后续处理
     * @param execution 流程信息
     */
    public abstract void handleTrue(DelegateExecution execution);

    /**
     * 当前置的UserTask的处理结果逻辑上为False时ServiceTask节点的后续处理
     * @param execution 流程信息
     */
    public abstract void handleFalse(DelegateExecution execution);

    /**
     * 获取历史任务
     * @param execution 流程信息
     * @return 历史任务
     */
    protected HistoricTaskInstance getHistoricTaskInstance(DelegateExecution execution){
        ProcessDefinition pd = repositoryUtil.getLatestProcessDefinitionById(execution.getProcessDefinitionId());
        HistoricTaskInstance historicTask = historyUtil.getHistoricTaskByProcessInstanceId(pd.getKey(), execution.getProcessInstanceId());
        if (historicTask == null){
            throw new WorkflowException(WorkflowExceptionEnum.UNKNOWN_HISTORIC_TASK);
        }
        return historicTask;
    }
}
